package com.lc.pianostudent.alipay;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.alipay.sdk.app.AuthTask;
import com.alipay.sdk.app.PayTask;
import com.lc.pianostudent.BaseApplication;
import com.lc.pianostudent.conn.Conn;


import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

public abstract class PayAction {
	/** 支付宝支付业务：入参app_id */
	public static final String APPID = "2018071960671521";
	// 商户PID
	public static final String PARTNER = "";
	// 商户收款账号
	public static final String SELLER = "";
	public static final String TARGET_ID  =System.currentTimeMillis()+"";
	// 商户私钥，pkcs8格式
	public static final String RSA_PRIVATE ="MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDGR03z/g7asDsZe3aDZe5HSHou0CGiWrjuacg9Y0BKRwjIE6ahFPCAM/qncKfadET75MwDB79oGIxvgagT1TY0MBo8vQXYbQJZqZKk4OhcBB3W5v/Xu1u/lCJlcOnY4zFs/6DzKHe+UZLzml+gt4nrp8IkLzAZlyironyl7RO71dtoSJH5e471gw4FDH8Ds8JjMCbOA2CBskOdJjFCMJduEYGLoh51YJer8g2F/VwwffGWkDJMMKGG3cPaYdFE2NTIf8Y/3zRDK1ldc3uFN2/Z/qiFtZemJL/cFiE3679Tkr8g9zRMgaPpa0aZkVEdSe7xtKc9kgfE3SPnhAnWzeuTAgMBAAECggEAZnvgjOaaIurIAUnRXeVHncyWaq/lUpd10rUWbLRqPHouzctqawP5syoqunT+LWm/ZjtCP6a3hkR6AgCQMYAYvizGwvIonU7q0hFV3KbrMvRlv/gx8P3EVGdqx+fu1s3HdEFEnaojCln7jLIUD2wOe6GANVe2kuOQf/ZCWzkI5CKimBrfUzpAsjyzHn94mdRzcqhX2nqiaId+57R+r0kECumBx374sgaz1SXBezJZSegzDkAPUqtekdZB1MnabMgtgJgblq42fPN8n8IpjlK3Z2uzOWDwzBVuFjE2m6F3z92HxKnqqu6qZAktSWrlOS4WBD0i6/tqHFXhGpP1t6eyMQKBgQDh77h9SxthZFGIuPBX7fA04uN95c34rQi9rOG+OM/7Bu11toFHPp3TqsLZIiIs9nfx4zRK8NfLGliTeR1ABHjfci3cYaIzzhLWVxVhFtTYO75ZyAG1R57kXiwe8TeLRcMrD5zO4duMeCVhCI99R2Z0qFBTI/9KbOy5+w10hZ2M9wKBgQDgqXK/SBToHFw9dml07oSPPwFDW//sLrt0I6mQjrzkYVrwJlHL0yx2+wVJVP/lDmQJPBRStkXMdEC4pb2NcA6+goTJ6M4Ya7Wp+0RxhOtWl9WL7s89o9Z6iHRVdj1QcdSo5QIw5rdnNpm6j2swK+WwxfHPSuARAYrzvMC0RnY7RQKBgDTScNWKK7qXU6CdbEOCc3hJ21nh0kfjXHnL43MvoSBVPEsbAhp//zIvaCKPomHUtbItplom+KyZWkAQPtBquz+yWBqAEQX/ldPaxDrQta5gOV6QLiYNuo41nicVyiCbjMeSfNy5XTT4GfUXpURq3v9DIpRthBAIa0gH89tcKbt9AoGAA90GGyH7Mg6iy2/I2njrkKcNt4HSgdY/5PxkAxdhSjAeZzjReUbVYeppKdyrVd4MfFgrJUz7IEvzfPlkrBT8O+x0qiA1wxe/FQA8KhOWFHQh+PkPWUkC/DJyhbG11jdO5+SgSAT/rGe09w9WUYq/tW2B/gWUmtZC9HQPgEoh6F0CgYA+G283r3X33RPGxJWpd9zM/qQ0RWOxhgcCxw//NE0kXsxRPF3xnP+s0JrE+fiyVsSTgjLZb2zV06EFDtsJZ04CNYdReoHGGVjYiC+NwfwVZfeMduiZLK3sX8rV7iKGFkLXJLO02aq+m0TBAyiGVCI/WhogTGKNkV8IjQaLXKjb+A==";
	public static final String RSA2_PRIVATE ="MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDGR03z/g7asDsZe3aDZe5HSHou0CGiWrjuacg9Y0BKRwjIE6ahFPCAM/qncKfadET75MwDB79oGIxvgagT1TY0MBo8vQXYbQJZqZKk4OhcBB3W5v/Xu1u/lCJlcOnY4zFs/6DzKHe+UZLzml+gt4nrp8IkLzAZlyironyl7RO71dtoSJH5e471gw4FDH8Ds8JjMCbOA2CBskOdJjFCMJduEYGLoh51YJer8g2F/VwwffGWkDJMMKGG3cPaYdFE2NTIf8Y/3zRDK1ldc3uFN2/Z/qiFtZemJL/cFiE3679Tkr8g9zRMgaPpa0aZkVEdSe7xtKc9kgfE3SPnhAnWzeuTAgMBAAECggEAZnvgjOaaIurIAUnRXeVHncyWaq/lUpd10rUWbLRqPHouzctqawP5syoqunT+LWm/ZjtCP6a3hkR6AgCQMYAYvizGwvIonU7q0hFV3KbrMvRlv/gx8P3EVGdqx+fu1s3HdEFEnaojCln7jLIUD2wOe6GANVe2kuOQf/ZCWzkI5CKimBrfUzpAsjyzHn94mdRzcqhX2nqiaId+57R+r0kECumBx374sgaz1SXBezJZSegzDkAPUqtekdZB1MnabMgtgJgblq42fPN8n8IpjlK3Z2uzOWDwzBVuFjE2m6F3z92HxKnqqu6qZAktSWrlOS4WBD0i6/tqHFXhGpP1t6eyMQKBgQDh77h9SxthZFGIuPBX7fA04uN95c34rQi9rOG+OM/7Bu11toFHPp3TqsLZIiIs9nfx4zRK8NfLGliTeR1ABHjfci3cYaIzzhLWVxVhFtTYO75ZyAG1R57kXiwe8TeLRcMrD5zO4duMeCVhCI99R2Z0qFBTI/9KbOy5+w10hZ2M9wKBgQDgqXK/SBToHFw9dml07oSPPwFDW//sLrt0I6mQjrzkYVrwJlHL0yx2+wVJVP/lDmQJPBRStkXMdEC4pb2NcA6+goTJ6M4Ya7Wp+0RxhOtWl9WL7s89o9Z6iHRVdj1QcdSo5QIw5rdnNpm6j2swK+WwxfHPSuARAYrzvMC0RnY7RQKBgDTScNWKK7qXU6CdbEOCc3hJ21nh0kfjXHnL43MvoSBVPEsbAhp//zIvaCKPomHUtbItplom+KyZWkAQPtBquz+yWBqAEQX/ldPaxDrQta5gOV6QLiYNuo41nicVyiCbjMeSfNy5XTT4GfUXpURq3v9DIpRthBAIa0gH89tcKbt9AoGAA90GGyH7Mg6iy2/I2njrkKcNt4HSgdY/5PxkAxdhSjAeZzjReUbVYeppKdyrVd4MfFgrJUz7IEvzfPlkrBT8O+x0qiA1wxe/FQA8KhOWFHQh+PkPWUkC/DJyhbG11jdO5+SgSAT/rGe09w9WUYq/tW2B/gWUmtZC9HQPgEoh6F0CgYA+G283r3X33RPGxJWpd9zM/qQ0RWOxhgcCxw//NE0kXsxRPF3xnP+s0JrE+fiyVsSTgjLZb2zV06EFDtsJZ04CNYdReoHGGVjYiC+NwfwVZfeMduiZLK3sX8rV7iKGFkLXJLO02aq+m0TBAyiGVCI/WhogTGKNkV8IjQaLXKjb+A==";


	private static final int SDK_PAY_FLAG = 1;
	private static final int SDK_AUTH_FLAG = 2;

	private OnALiAuthLoginCallBack mOnALiAuthLoginCallBack;

	private Activity activity;

	public PayAction(Activity activity){
		this.activity = activity;
	}

	@SuppressLint("HandlerLeak")
	private Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {

			switch (msg.what) {

				case SDK_PAY_FLAG: {
					@SuppressWarnings("unchecked")
					PayResult payResult = new PayResult((Map<String, String>) msg.obj);
					/**
					 对于支付结果，请商户依赖服务端的异步通知结果。同步通知结果，仅作为支付结束的通知。
					 */
					String resultInfo = payResult.getResult();// 同步返回需要验证的信息
					String resultStatus = payResult.getResultStatus();
					// 判断resultStatus 为9000则代表支付成功
					Log.e("返回结果:",resultStatus);
					if (TextUtils.equals(resultStatus, "9000")) {
						// 该笔订单是否真实支付成功，需要依赖服务端的异步通知。
						Toast.makeText(activity, "支付成功", Toast.LENGTH_SHORT).show();
						onSuccess();
					} else {
						// 该笔订单真实的支付结果，需要依赖服务端的异步通知。
						Toast.makeText(activity, "支付失败", Toast.LENGTH_SHORT).show();
						onEnd();
					}
					break;
				}
				case SDK_AUTH_FLAG: {
					@SuppressWarnings("unchecked")
					AuthResult authResult = new AuthResult((Map<String, String>) msg.obj, true);
					String resultStatus = authResult.getResultStatus();

					// 判断resultStatus 为“9000”且result_code
					// 为“200”则代表授权成功，具体状态码代表含义可参考授权接口文档
					if (TextUtils.equals(resultStatus, "9000") && TextUtils.equals(authResult.getResultCode(), "200")) {
						// 获取alipay_open_id，调支付时作为参数extern_token 的value
						// 传入，则支付账户为该授权账户
						/*Toast.makeText(activity,
								"授权成功\n" + String.format("authCode:%s", authResult.getAlipayOpenId()), Toast.LENGTH_SHORT)
								.show();*/
						Log.e("支付宝登录返回:",authResult.getResult());
                        String result = authResult.getResult();
                        String[] split = result.split("&");
                        String[] split1 = split[5].split("=");
                        String[] split2 = split[6].split("=");

                        Log.e("支付宝登录返回:",split1[1] + "::" + split2[1]);
                        if(mOnALiAuthLoginCallBack !=null){
							mOnALiAuthLoginCallBack.onAliCallBack(split1[1],split2[1]);
						}
					} else {
						// 其他状态值则为授权失败
						Toast.makeText(activity,
								"授权失败" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT).show();

					}

					break;
				}
				default:
					break;
			}
		};
	};

	/**
	 * call alipay sdk pay. 调用SDK支付
	 *
	 */
	public void pay(String money, String state, String title, String orderId) throws Exception{

		if (TextUtils.isEmpty(APPID) || (TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE))) {
			new AlertDialog.Builder(activity).setTitle("警告").setMessage("需要配置APPID | RSA_PRIVATE")
					.setPositiveButton("确定", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialoginterface, int i) {
							//
							activity.finish();
						}
					}).show();
			return;
		}

		/**
		 * 这里只是为了方便直接向商户展示支付宝的整个支付流程；所以Demo中加签过程直接放在客户端完成；
		 * 真实App里，privateKey等数据严禁放在客户端，加签过程务必要放在服务端完成；
		 * 防止商户私密数据泄露，造成不必要的资金损失，及面临各种安全风险；
		 *
		 * orderInfo的获取必须来自服务端；
		 */
		boolean rsa2 = (RSA2_PRIVATE.length() > 0);
		Map<String, String> params = OrderInfoUtil2_0.buildOrderParamMap(APPID, rsa2,money,state,title,orderId);
		String orderParam = OrderInfoUtil2_0.buildOrderParam(params);

		String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;
		String sign = OrderInfoUtil2_0.getSign(params, privateKey, rsa2);
		final String orderInfo = orderParam + "&" + sign;

		Runnable payRunnable = new Runnable() {

			@Override
			public void run() {
				PayTask alipay = new PayTask(activity);
				Map<String, String> result = alipay.payV2(orderInfo, true);
				Log.i("msp", result.toString());

				Message msg = new Message();
				msg.what = SDK_PAY_FLAG;
				msg.obj = result;
				mHandler.sendMessage(msg);
			}
		};

		Thread payThread = new Thread(payRunnable);
		payThread.start();

	}
	/**
	 * 构造支付订单参数列表
	 * pid
	 * app_id
	 * target_id
	 *
	 */
	public static Map<String, String> buildOrderParamMap(String app_id, boolean rsa2,String subject,String state,String trade_no,String total_fee) {
		Map<String, String> keyValues = new HashMap<String, String>();

		keyValues.put("app_id", app_id);

		keyValues.put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\""+total_fee+"\",\"subject\":\""+subject+"\",\"body\":\""+state+"\",\"out_trade_no\":\"" + trade_no +  "\"}");

		keyValues.put("notify_url", Conn.SERVICE+ Conn.ALIPAY_NOTIFYURL);

		keyValues.put("charset", "utf-8");

		keyValues.put("method", "alipay.trade.app.pay");

		keyValues.put("sign_type", rsa2 ? "RSA2" : "RSA");

		keyValues.put("timestamp", "2016-07-29 16:55:53");

		keyValues.put("version", "1.0");

		return keyValues;
	}



	/**
	 * 构造支付订单参数信息
	 *
	 * @param map
	 * 支付订单参数
	 * @return
	 */
	public static String buildOrderParam(Map<String, String> map) {
		List<String> keys = new ArrayList<String>(map.keySet());

		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < keys.size() - 1; i++) {
			String key = keys.get(i);
			String value = map.get(key);
			sb.append(buildKeyValue(key, value, true));
			sb.append("&");
		}

		String tailKey = keys.get(keys.size() - 1);
		String tailValue = map.get(tailKey);
		sb.append(buildKeyValue(tailKey, tailValue, true));

		return sb.toString();
	}
	/**
	 * 要求外部订单号必须唯一。
	 * @return
	 */
	private static String getOutTradeNo() {
		SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());
		Date date = new Date();
		String key = format.format(date);

		Random r = new Random();
		key = key + r.nextInt();
		key = key.substring(0, 15);
		return key;
	}
	/**
	 * 拼接键值对
	 *
	 * @param key
	 * @param value
	 * @param isEncode
	 * @return
	 */
	private static String buildKeyValue(String key, String value, boolean isEncode) {
		StringBuilder sb = new StringBuilder();
		sb.append(key);
		sb.append("=");
		if (isEncode) {
			try {
				sb.append(URLEncoder.encode(value, "UTF-8"));
			} catch (UnsupportedEncodingException e) {
				sb.append(value);
			}
		} else {
			sb.append(value);
		}
		return sb.toString();
	}
	/**
	 * sign the order info. 对订单信息进行签名
	 *
	 * @param待签名订单信息
	 */
	public static String getSign(Map<String, String> map, String rsaKey, boolean rsa2) {
		List<String> keys = new ArrayList<String>(map.keySet());
		// key排序
		Collections.sort(keys);

		StringBuilder authInfo = new StringBuilder();
		for (int i = 0; i < keys.size() - 1; i++) {
			String key = keys.get(i);
			String value = map.get(key);
			authInfo.append(buildKeyValue(key, value, false));
			authInfo.append("&");
		}

		String tailKey = keys.get(keys.size() - 1);
		String tailValue = map.get(tailKey);
		authInfo.append(buildKeyValue(tailKey, tailValue, false));

		String oriSign = SignUtils.sign(authInfo.toString(), rsaKey, rsa2);
		String encodedSign = "";

		try {
			encodedSign = URLEncoder.encode(oriSign, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "sign=" + encodedSign;
	}


	public void authV2() {
		if (TextUtils.isEmpty(PARTNER) || TextUtils.isEmpty(APPID)
				|| (TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE))
				|| TextUtils.isEmpty(TARGET_ID)) {
			new AlertDialog.Builder(BaseApplication.getContext()).setTitle("警告").setMessage("需要配置PARTNER |APP_ID| RSA_PRIVATE| TARGET_ID")
					.setPositiveButton("确定", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialoginterface, int i) {
						}
					}).show();
			return;
		}

		/**
		 * 这里只是为了方便直接向商户展示支付宝的整个支付流程；所以Demo中加签过程直接放在客户端完成；
		 * 真实App里，privateKey等数据严禁放在客户端，加签过程务必要放在服务端完成；
		 * 防止商户私密数据泄露，造成不必要的资金损失，及面临各种安全风险；
		 *
		 * authInfo的获取必须来自服务端；
		 */
		boolean rsa2 = (RSA2_PRIVATE.length() > 0);
		Map<String, String> authInfoMap = OrderInfoUtil2_0.buildAuthInfoMap(PARTNER, APPID, TARGET_ID, rsa2);
		String info = OrderInfoUtil2_0.buildOrderParam(authInfoMap);

		String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;
		String sign = OrderInfoUtil2_0.getSign(authInfoMap, privateKey, rsa2);
		final String authInfo = info + "&" + sign;
		Runnable authRunnable = new Runnable() {

			@Override
			public void run() {
				// 构造AuthTask 对象
				AuthTask authTask = new AuthTask(activity);
				// 调用授权接口，获取授权结果
				Map<String, String> result = authTask.authV2(authInfo, true);

				Message msg = new Message();
				msg.what = SDK_AUTH_FLAG;
				msg.obj = result;
				mHandler.sendMessage(msg);
			}
		};

		// 必须异步调用
		Thread authThread = new Thread(authRunnable);
		authThread.start();
	}

	/**
	 * get the sign type we use. 获取签名方式
	 *
	 */
	public String getSignType() {
		return "sign_type=\"RSA\"";
	}

	public interface OnALiAuthLoginCallBack{

		void onAliCallBack(String alipay_open_id, String user_id);

	}

	public void setOnALiAuthLoginCallBack(OnALiAuthLoginCallBack mOnALiAuthLoginCallBack){
		this.mOnALiAuthLoginCallBack = mOnALiAuthLoginCallBack;
	}
	protected abstract void onSuccess();

	protected abstract void onEnd();

}
